package com.hitqz.robot.biz.flow.component.patrol;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.hitqz.robot.api.business.enums.MediaEnum;
import com.hitqz.robot.api.business.model.dto.FlowContextDto;
import com.hitqz.robot.api.business.model.dto.FlowPatrolTicketsDto;
import com.hitqz.robot.api.common.entity.*;
import com.hitqz.robot.biz.core.FileProperties;
import com.hitqz.robot.biz.service.*;
import com.hitqz.robot.camera.EquipmentFactory;
import com.hitqz.robot.camera.IEquipmentService;
import com.hitqz.robot.camera.configure.EquipmentCmdEnum;
import com.hitqz.robot.camera.dto.AreaTemplateDTO;
import com.hitqz.robot.camera.dto.InitRegionMeasureDTO;
import com.hitqz.robot.camera.dto.MeasureTemplateDto;
import com.hitqz.robot.camera.dto.QueryParamsDto;
import com.hitqz.robot.camera.entity.TemplateArea;
import com.yomahub.liteflow.annotation.LiteflowComponent;
import com.yomahub.liteflow.core.NodeComponent;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.web.ServerProperties;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.*;

@Slf4j
@LiteflowComponent(value = "Detect", name = "[巡检]视觉检测/测温")
@AllArgsConstructor
public class Detect extends NodeComponent {

    private final RobotService robotService;

    private final RobotEquipmentService robotEquipmentService;

    private final EquipmentFactory equipmentFactory;

    private final PatrolItemService patrolItemService;

    private final PatrolObjectService patrolObjectService;

    private final PatrolCheckTypeService patrolCheckTypeService;

    private final PatrolItemMarkService patrolItemMarkService;

    private final ServerProperties serverProperties;

    private final FileProperties fileProperties;

    @Override
    public void process() throws Exception {
        FlowContextDto dto = this.getRequestData();
        TicketsTask task = dto.getTicketsTask();
        log.info("任务数据 {}", task.getParseOrderParams());
        FlowPatrolTicketsDto params = JSONObject.parseObject(task.getParseOrderParams(), FlowPatrolTicketsDto.class);
        log.info("{} ---params: {}", task.getParseOrderParams(), JSONObject.toJSONString(params));
        if (params.getDetectEquipmentId()==null || StrUtil.isBlank(params.getMediaUrl())){
            log.warn("没有图片信息,不执行");
            return;
        }
        //查找检测项
        Integer patrolItemId = params.getPatrolItemId();
        PatrolItem patrolItem = patrolItemService.getById(patrolItemId);
        PatrolObject patrolObject = patrolObjectService.getById(patrolItem.getPatrolObjectId());
        PatrolCheckType checkType = patrolCheckTypeService.getById(patrolObject.getPatrolCheckTypeId());
        if (Objects.equals(checkType.getIsVision(),1)){
            //视觉项
            String visionUrl = checkType.getVisionUrl();
            String type = checkType.getVisionType();
            Robot robot = robotService.getDefaultRobot();
            String externalIp = StrUtil.isBlank(robot.getExternalIp()) ? "127.0.0.1" : robot.getExternalIp();
            String externalHost = StrUtil.isBlank(robot.getExternalPort()) ? externalIp + ":" + serverProperties.getPort() : externalIp + ":" + robot.getExternalPort();
            String host = (visionUrl.contains("127.0.0.1") || visionUrl.contains("localhost")) ? "127.0.0.1:"+ serverProperties.getPort() : externalHost;
            // 编码，避免#等特殊符号
            String url = "http://"+ host + "/file/" + params.getMediaUrl();
            HashMap<String, Object> query = new HashMap<>();
            query.put("url",url);
            query.put("rectype",Integer.parseInt(type));
            log.info("视觉地址：{},参数:{}",visionUrl,JSONObject.toJSONString(query));
            String result = HttpUtil.post(visionUrl, JSONObject.toJSONString(query), 2500);
            log.info("视觉检测结果: {}", result);
            if (StrUtil.isNotBlank(result)){
                JSONObject jsonObject = JSONObject.parseObject(result);
                Integer code = jsonObject.getInteger("code");
                if (Objects.equals(code, 200)) {
                    if (StrUtil.isNotBlank(jsonObject.getString("result"))) {
                        params.setResult(jsonObject.getString("result").replace("a","").replace("b","").replace("c",""));
                    }
                    if (StrUtil.isNotBlank(jsonObject.getString("path"))) {
                        String path = downloadImage(jsonObject.getString("path"));
                        if (StrUtil.isNotBlank(path)){
                            params.setVisionUrl(path);
                        }else {
                            params.setVisionUrl(params.getMediaUrl());
                        }

                    }
                }else {
                    // todo 报警 写入记录 url要编码处理

                }
            }
        }else if (Objects.equals(checkType.getMediaType(), MediaEnum.THERMOMETRY.getType())){
            //测温项
            RobotEquipment channel = robotEquipmentService.getById(params.getDetectEquipmentId());
            IEquipmentService service = equipmentFactory.getServiceByBrand(channel.getBrand());
            InitRegionMeasureDTO initRegionMeasureDTO = new InitRegionMeasureDTO();
            initRegionMeasureDTO.setIp(channel.getIp());
            PatrolItemMark itemMark = patrolItemMarkService.getOne(Wrappers.<PatrolItemMark>lambdaQuery().eq(PatrolItemMark::getPatrolItemId, patrolItemId).last("limit 1"));
            initRegionMeasureDTO.setTemplateAreas(this.getTemplateArea(itemMark));
            //List<Integer> ruleIdList = service.initRegionAndStartMonitor(initRegionMeasureDTO);
            QueryParamsDto queryParamsDto = new QueryParamsDto();
            queryParamsDto.setChannel(channel.getChannel());
            queryParamsDto.setPort(channel.getPort());
            queryParamsDto.setPassword(channel.getPassword());
            queryParamsDto.setUsername(channel.getUsername());
            queryParamsDto.setIp(channel.getIp());

            MeasureTemplateDto ruleDto = (MeasureTemplateDto) service.executeCmd(
                    queryParamsDto, true, EquipmentCmdEnum.INIT_REGION_AND_START_MONITOR, initRegionMeasureDTO
            );
            initRegionMeasureDTO.setRuleIdList(ruleDto.getConfig());
            Thread.sleep(2500);
            //AreaTemplateDTO areaTemplateDTO = service.stopRegionMonitor(initRegionMeasureDTO);
            AreaTemplateDTO areaTemplateDTO = (AreaTemplateDTO) service.executeCmd(queryParamsDto, true,
                    EquipmentCmdEnum.STOP_MONITOR, initRegionMeasureDTO);
            params.setResult(String.valueOf(areaTemplateDTO.getMaxTemplate()));
        }
        //结果传递到上下文参数
        task.setParseOrderParams(JSONObject.toJSONString(params));
    }

    private List<TemplateArea> getTemplateArea(PatrolItemMark itemMar){
        List<TemplateArea> areaList = new ArrayList<>();
        if (itemMar == null || itemMar.getX1()==null){
            return areaList;
        }else {
            TemplateArea templateArea = new TemplateArea();
            templateArea.setCheckItemId(itemMar.getPatrolItemId());
            int height = 1280;
            int width = 720;
            try {
                String localUrl = "http://127.0.0.1:" + serverProperties.getPort() + "/file/" + itemMar.getUrl();
                URL url = new URL(localUrl.replace("\\","/"));
                BufferedImage picture = ImageIO.read(url);
                height = picture.getHeight();
                width = picture.getWidth();
            } catch (Exception e) {
                log.error("[track]get mark picture error:{},{}",itemMar.getUrl(),e.getMessage());
            }
            int sdkX1 = itemMar.getX1() * 1000 / width;
            int sdkY1 = itemMar.getY1() * 1000 / height;
            int sdkX2 = itemMar.getX2() * 1000 / width;
            int sdkY2 = itemMar.getY2() * 1000 / height;
            templateArea.setUpperLeftPos(sdkX1+","+sdkY1);
            templateArea.setBottomRightPos(sdkX2+","+sdkY2);
            templateArea.setUpperRightPos(sdkX2+","+sdkY1);
            templateArea.setBottomLeftPos(sdkX1+","+sdkY2);
            areaList.add(templateArea);
            return areaList;
        }
    }


    /**
     * 下载图片到本地
     * @param imageUrl 视觉 url
     * @return url 本地的相对路径
     */
    private String downloadImage(String imageUrl) {
        InputStream in = null;
        String relativePath =  File.separator + "vision_draw" + File.separator + DateUtil.format(new Date(),"yyyyMMdd") + File.separator + DateUtil.format(new Date(),"yyyyMMddHHmmssSSS") + ".jpg";
        String path = fileProperties.getLocal().getBasePath() + relativePath;
        try  {  // 打开输入流
            URL url = new URL(imageUrl.replace("/./","/"));  // 创建 URL 对象
            in = url.openStream();
            FileUtil.writeFromStream(in,path);
            return relativePath;
        } catch (IOException e) {
            log.error("down vision picture error:{}",e.getMessage());
            return "";
        } finally {
            try {
                if (in!=null) {
                    in.close();
                }
            } catch (IOException e) {
                log.error("InputStream close error:{}",e.getMessage());
            }
        }
    }



}